package com.sky.utils;

/**
 * @author dongdong 抖音号：W13883155245
 * @version 1.0
 * @date 2025/10/5
 * @description
 */
import com.google.zxing.*;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;

/**
 * Java 二维码生成工具类（基于ZXing）
 */
public class QrCodeGenerator {

    // 默认二维码配置（可根据需求调整）
    private static final int DEFAULT_WIDTH = 200;    // 默认宽度（像素）
    private static final int DEFAULT_HEIGHT = 200;   // 默认高度（像素）
    private static final String DEFAULT_FORMAT = "PNG"; // 默认图片格式
    private static final ErrorCorrectionLevel DEFAULT_ERROR_LEVEL = ErrorCorrectionLevel.M; // 容错级别（M级：可容错15%）
    private static final Color DEFAULT_FOREGROUND_COLOR = Color.BLACK; // 前景色（二维码颜色）
    private static final Color DEFAULT_BACKGROUND_COLOR = Color.WHITE; // 背景色

    /**
     * 生成二维码并写入输出流（适用于后端返回给前端）
     * @param content 二维码内容（如URL、文本）
     * @param outputStream 输出流（如HttpServletResponse的输出流）
     * @throws WriterException 编码异常
     * @throws IOException IO异常
     */
    public static void generateQrCodeToStream(String content, OutputStream outputStream)
            throws WriterException, IOException {
        generateQrCodeToStream(content, DEFAULT_WIDTH, DEFAULT_HEIGHT, outputStream);
    }

    /**
     * 自定义宽高生成二维码到输出流
     */
    public static void generateQrCodeToStream(String content, int width, int height, OutputStream outputStream)
            throws WriterException, IOException {
        // 1. 配置二维码参数
        Map<EncodeHintType, Object> hints = new HashMap<>();
        hints.put(EncodeHintType.CHARACTER_SET, "UTF-8"); // 字符编码（避免中文乱码）
        hints.put(EncodeHintType.ERROR_CORRECTION, DEFAULT_ERROR_LEVEL); // 容错级别
        hints.put(EncodeHintType.MARGIN, 1); // 二维码边距（0-4，越小越紧凑）

        // 2. 生成二维码矩阵（BitMatrix）
        BitMatrix bitMatrix = new MultiFormatWriter().encode(
                content,          // 二维码内容
                BarcodeFormat.QR_CODE, // 条码类型（QR码）
                width, height,    // 宽高
                hints             // 配置参数
        );

        // 3. 将矩阵转换为图片并写入输出流
        MatrixToImageWriter.writeToStream(bitMatrix, DEFAULT_FORMAT, outputStream);
    }

    /**
     * 生成二维码并保存为本地文件
     * @param content 二维码内容
     * @param filePath 保存路径（如 "D:/wechat_login_qr.png"）
     * @throws WriterException 编码异常
     * @throws IOException IO异常
     */
    public static void generateQrCodeToFile(String content, String filePath)
            throws WriterException, IOException {
        generateQrCodeToFile(content, DEFAULT_WIDTH, DEFAULT_HEIGHT, filePath);
    }

    /**
     * 自定义宽高生成二维码到本地文件
     */
    public static void generateQrCodeToFile(String content, int width, int height, String filePath)
            throws WriterException, IOException {
        File file = new File(filePath);
        // 确保父目录存在
        if (!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
        }
        // 生成二维码并写入文件
        generateQrCodeToStream(content, width, height, new java.io.FileOutputStream(file));
    }

    /**
     * 生成带自定义颜色的二维码（如微信绿前景色）
     * @param content 二维码内容
     * @param width 宽度
     * @param height 高度
     * @param foregroundColor 前景色（二维码颜色）
     * @param backgroundColor 背景色
     * @return  BufferedImage 二维码图片对象（可进一步处理，如加水印）
     * @throws WriterException 编码异常
     */
    public static BufferedImage generateCustomColorQrCode(String content, int width, int height,
                                                          Color foregroundColor, Color backgroundColor)
            throws WriterException {
        Map<EncodeHintType, Object> hints = new HashMap<>();
        hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
        hints.put(EncodeHintType.ERROR_CORRECTION, DEFAULT_ERROR_LEVEL);
        hints.put(EncodeHintType.MARGIN, 1);

        // 生成矩阵
        BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, width, height, hints);

        // 自定义颜色渲染
        int matrixWidth = bitMatrix.getWidth();
        int matrixHeight = bitMatrix.getHeight();
        BufferedImage image = new BufferedImage(matrixWidth, matrixHeight, BufferedImage.TYPE_INT_RGB);

        for (int x = 0; x < matrixWidth; x++) {
            for (int y = 0; y < matrixHeight; y++) {
                // 黑色模块（true）用前景色，白色模块（false）用背景色
                image.setRGB(x, y, bitMatrix.get(x, y) ? foregroundColor.getRGB() : backgroundColor.getRGB());
            }
        }
        return image;
    }

    /**
     * 辅助方法：将BufferedImage转为字节数组（用于前端展示）
     */
    public static byte[] bufferedImageToBytes(BufferedImage image) throws IOException {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        ImageIO.write(image, DEFAULT_FORMAT, outputStream);
        return outputStream.toByteArray();
    }
}